package router

import (
	"git.huoys.com/block_chain/mall/ecode"
	pb "git.huoys.com/block_chain/mall/internal/shop/api"
	"git.huoys.com/block_chain/mall/internal/shop/model"
	"git.huoys.com/block_chain/mall/internal/shop/service"
	"git.huoys.com/block_chain/mall/pkg/app"
	"git.huoys.com/block_chain/mall/pkg/log"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type ShopHandler interface {
	// 添加商品类别
	AddClass(ctx *gin.Context)
	// 添加商品
	AddGood(ctx *gin.Context)
	// 删除商品
	DelGood(ctx *gin.Context)
	// 修改商品属性
	SetGood(ctx *gin.Context)
	// 根据分类查找商品
	GetGoodByClass(ctx *gin.Context)
	// 获取分类前几的商品
	GetGoodSByClassSorting(ctx *gin.Context)
	// 获取用户帐号下所有商品
	GetUserGoods(ctx *gin.Context)
	// 获取商品详细信息
	GetGoodInfo(ctx *gin.Context)
	// 上传图片地址
	UploadGoodImg(ctx *gin.Context)
	// 删除图片地址
	DelGoodImg(ctx *gin.Context)
	// 创建订单
	AddOrder(ctx *gin.Context)
	// 查询用户订单列表 可以分类
	GetOrderList(ctx *gin.Context)
	// 获取订单详情
	GetOrder(ctx *gin.Context)
}

type shopHandler struct {
	service service.ShopService
}

func NewShopHandler(s service.ShopService) ShopHandler {
	return &shopHandler{
		service: s,
	}
}

// 添加商品类别
func (c *shopHandler) AddClass(ctx *gin.Context) {
	var param = pb.AddClassReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.AddClassResp{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api AddClass app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	resp.Cid, err = c.service.AddClass(param.Name)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 添加商品
func (c *shopHandler) AddGood(ctx *gin.Context) {
	var param = pb.AddGoodReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.AddGoodResp{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api AddGood app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	resp.GoodId, err = c.service.AddGood(model.PbGoodsToGoods(*param.Goods, true), param.Uid)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 删除商品
func (c *shopHandler) DelGood(ctx *gin.Context) {
	var param = pb.DelGoodReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.Empty{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api DelGood app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	err = c.service.DelGood(param.GetGoodId())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 修改商品属性
func (c *shopHandler) SetGood(ctx *gin.Context) {
	var param = pb.SetGoodReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.Empty{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api SetGood app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	err = c.service.SetGood(model.PbGoodsToGoods(*param.Goods, false))
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 根据分类查找商品
func (c *shopHandler) GetGoodByClass(ctx *gin.Context) {
	var param = pb.GetGoodByClassReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.GetGoodByClassResp{}
	var err error
	var goodList []*model.GoodsList
	var count uint64
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetGoodByClass app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	goodList, count, err = c.service.GetGoodByClass(param.GetClassId(), param.GetLastId(), param.GetLimit())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	var goods = model.ToPbGoodsList(goodList)
	resp = pb.GetGoodByClassResp{
		GoodsList: goods,
		Count:     count,
	}
	response.ToResponse(resp)
	return
}

// 获取分类前几的商品
func (c *shopHandler) GetGoodSByClassSorting(ctx *gin.Context) {
	var param = pb.GetGoodSByClassSortingReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.GetGoodSByClassSortingResp{}
	var err error
	var goodList []*model.GoodsList
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetGoodSByClassSorting app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	goodList, err = c.service.GetGoodSByClassSorting(param.Num)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	var goods = model.ToPbGoodsList(goodList)
	resp = pb.GetGoodSByClassSortingResp{
		GoodsList: goods,
	}
	response.ToResponse(resp)
	return
}

// 获取用户帐号下所有商品
func (c *shopHandler) GetUserGoods(ctx *gin.Context) {
	var param = pb.GetUserGoodSReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.GetUserGoodSResp{}
	var err error
	var goodList []*model.GoodsList
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetUserGoods app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	goodList, err = c.service.GetUserGoods(param.GetUid())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	var goods = model.ToPbGoodsList(goodList)
	resp = pb.GetUserGoodSResp{
		GoodsList: goods,
	}
	response.ToResponse(resp)
	return
}

// 获取商品详细信息
func (c *shopHandler) GetGoodInfo(ctx *gin.Context) {
	var param = pb.GetGoodInfoReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.GetGoodInfoResp{}
	var err error
	var imgs []model.ImgS
	var goods model.Goods
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetGoodInfo app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	imgs, goods, err = c.service.GetGoodInfo(param.GoodsId)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	resp.Goods = new(pb.Goods)
	resp.Goods = goods.ToGoodsPb()
	resp.Goods.Imgs = model.ToImgsToPbImgs(imgs)
	response.ToResponse(resp)
	return
}

// 上传图片地址
func (c *shopHandler) UploadGoodImg(ctx *gin.Context) {
	var param = pb.UploadGoodImgReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.Empty{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api UploadGoodImg app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	err = c.service.UploadGoodImg(param.GetGoodsId(), param.GetUrl(), param.GetIsMaster())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 删除图片地址
func (c *shopHandler) DelGoodImg(ctx *gin.Context) {
	var param = pb.DelGoodImgReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.Empty{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api DelGoodImg app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	err = c.service.DelGoodImg(param.GetGoodsId(), param.GetImgId())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 创建订单
func (c *shopHandler) AddOrder(ctx *gin.Context) {
	var param = pb.AddOrderReq{}
	var response = app.NewResponse(ctx)
	var resp = pb.AddOrderResp{}
	var err error
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api AddOrder app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	resp.Oid, err = c.service.AddOrder(param.Uid, param.GoodsId)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(resp)
	return
}

// 查询用户订单列表 可以分类
func (c *shopHandler) GetOrderList(ctx *gin.Context) {
	var param = pb.GetOrderSReq{}
	var response = app.NewResponse(ctx)
	var err error
	var order []model.Order
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetOrderList app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	order, err = c.service.GetOrderList(param.Uid, uint64(param.GetStatus()))
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(order)
	return
}

// 查询用户订单列表 可以分类
func (c *shopHandler) GetOrder(ctx *gin.Context) {
	var param = pb.GetOrderReq{}
	var response = app.NewResponse(ctx)
	var err error
	var order model.Order
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		log.GetLogger().Error("api GetOrder app.BindAndValid failed",
			zap.Any("param", param),
			zap.Any("errs", errs),
		)
		response.ToErrorResponse(ecode.ParamErr)
		return
	}
	order, err = c.service.GetOrder(param.GetOid())
	if err != nil {
		response.ToErrorResponse(err)
		return
	}
	response.ToResponse(order)
	return
}
